/*
  Program: Mine Mayhem
  File:    sound.cc
  Date:    26 October to 3 December, 1997,    version 2.00
	   8 December to 4 January,  2001,    version 2.10
	   15 January,			      version 2.11
	   18 September to 16 December, 2006, version 2.90

  The sound configuration dialog box.

  Freeware, Copyright 2001 Jason Hood.
*/

#include "sound.h"

#define ID_CHECK_SOUND	   1000
#define ID_CHECK_SWAP	   1001
#define ID_CHECK_OPEN	   1002
#define ID_CHECK_MARK	   1003
#define ID_CHECK_WIN	   1004
#define ID_CHECK_DIE	   1005


DEFINE_RESPONSE_TABLE(SoundDlg, TabWin)
   E_BUTTONUP(ID_OK, cmOK)
   E_BUTTONUP(ID_CANCEL, cmCancel)
END_RESPONSE_TABLE


// The following is an attempt to provide some "constants" for drawing check-
// boxes.  It's only reasonably successful.  I should add it to options.cc but
// I'm not going to because I don't want to cause myself more frustation.
// (It should really be placed in something like a CheckBoxContainer class; or
// even better, a combined radio-button and checkbox container.)
static int ONE_SPACE,
	   TWO_SPACES;
#define ONEBOLDRESTNORMAL(b, n) \
  (CharWidth((b), SysFontBold) + StringWidth((n), SysFont))
#define CHECK_BOX_BOX_WIDTH 12
#define CHECK_BOX_LENGTH(b, n) \
  (CHECK_BOX_BOX_WIDTH + TWO_SPACES + ONEBOLDRESTNORMAL((b), (n)) + ONE_SPACE)
#define CHECK_BOX_FRAME_WIDTH  (2 + 2)
#define CHECK_BOX_FRAME_HEIGHT (2 + 1)
#define CHECK_BOX_GAP SysFont->height+2


#define DLG_WIDTH  (SysFont->width*26)
#define DLG_HEIGHT (SysFont->height*13)

static int snddlg_cbwid[3];
static int snddlg_olwid[3];

SoundDlg::SoundDlg() :
  TabWin(NULL, "Sound",
	 (ws.GetDeskWidth()  - DLG_WIDTH) / 2,
	 (ws.GetDeskHeight() - DLG_HEIGHT) / 2,
	 (ws.GetDeskWidth()  + DLG_WIDTH) / 2 - 1,
	 (ws.GetDeskHeight() + DLG_HEIGHT) / 2 - 1,
         WA_VISABLE | WA_BORDER | WA_CAPTION | WA_SAVEAREA),
  isOK(false)
{
  ONE_SPACE  = CharWidth(' ', SysFont);
  TWO_SPACES = 2*ONE_SPACE;
  snddlg_cbwid[0] = ONEBOLDRESTNORMAL('S', "ound") + ONE_SPACE;
  snddlg_olwid[0] = CHECK_BOX_LENGTH('S', "ound") + 2*CHECK_BOX_FRAME_WIDTH;
  snddlg_cbwid[1] = ONEBOLDRESTNORMAL('O', "pen") + ONE_SPACE;
  snddlg_olwid[1] = CHECK_BOX_LENGTH('O', "pen") + 2*CHECK_BOX_FRAME_WIDTH;
  snddlg_cbwid[2] = ONEBOLDRESTNORMAL('p', "Swa Stereo") + ONE_SPACE;
  snddlg_olwid[2] = CHECK_BOX_LENGTH('p',"Swa Stereo")+2*CHECK_BOX_FRAME_WIDTH;

  int ox, oy, by, wid;

  wid = snddlg_cbwid[0];
  ox = (DLG_WIDTH - snddlg_olwid[0]) / 2 + CHECK_BOX_FRAME_WIDTH;
  oy = FWIDTH + CAPTION_HEIGHT + 8 + CHECK_BOX_FRAME_HEIGHT;
  sound = new CheckBox(this, ID_CHECK_SOUND, "&Sound", ox, oy, wid, isSound);

  wid = snddlg_cbwid[1];
  ox = FWIDTH + 8 + CHECK_BOX_FRAME_WIDTH;
  oy += CHECK_BOX_GAP + 2*CHECK_BOX_FRAME_HEIGHT + SysFont->height;
  by = oy + CHECK_BOX_GAP;
  open = new CheckBox(this, ID_CHECK_OPEN, "&Open", ox, oy, wid, OpenSnd);
  mark = new CheckBox(this, ID_CHECK_MARK, "&Mark", ox, by, wid, MarkSnd);

  ox = DLG_WIDTH - (FWIDTH + 8 + snddlg_olwid[1]) + CHECK_BOX_FRAME_WIDTH - 1;
  win  = new CheckBox(this, ID_CHECK_WIN, "&Win", ox, oy, wid, WinSnd);
  die  = new CheckBox(this, ID_CHECK_DIE, "&Die", ox, by, wid, DieSnd);

  wid = snddlg_cbwid[2];
  ox = (DLG_WIDTH - snddlg_olwid[2]) / 2 + CHECK_BOX_FRAME_WIDTH;
  oy += 2*CHECK_BOX_GAP + 2*CHECK_BOX_FRAME_HEIGHT + SysFont->height;
  swap = new CheckBox(this,ID_CHECK_SWAP, "Swa&p Stereo", ox,oy,wid,SwapStereo);

  wid = 10*SysFont->width; int hyt = SysFontBold->height+4;
  ox = (DLG_WIDTH- wid*2 - 10)/2;
  oy = cy2 - hyt - 8;
  OK = new TextButton(this, ID_OK, ox, oy, ox+wid-1, oy+hyt-1, "O&K");
  Cancel = new TextButton(this, ID_CANCEL, ox+wid+10, oy,
                          ox+wid+10+wid-1, oy+hyt-1, "&Cancel");

  AddTabStop(sound);
  AddTabStop(open);
  AddTabStop(mark);
  AddTabStop(win);
  AddTabStop(die);
  AddTabStop(swap);
  AddTabStop(OK);
  AddTabStop(Cancel);
}


SoundDlg::~SoundDlg()
{
  delete OK;	delete Cancel;
  delete sound; delete swap;
  delete open;	delete mark;
  delete win;	delete die;
}


// Draw a dipped frame for the rectangle (x1, y1) - (x2, y2).
// The dip is the rectangle (x1, y1) - (x2-1, y2-1).  Its highlight is the
// rectangle (x1+1, y1+1) - (x2, y2).
static void DipFrame(ViewBuffer* buf, int x1, int y1, int x2, int y2)
{
  HDip(buf, x1,   x2-1, y1);
  VDip(buf, x1,   y1+1, y2);
  HDip(buf, x1,   x2,	y2-1);
  VDip(buf, x2-1, y1+1, y2-1);
}


void SoundDlg::PaintWindow(int x1, int y1, int x2, int y2)
{
  TabWin::PaintWindow(x1, y1, x2, y2);

  ViewBuffer* buf = GetSubBuffer(x1, y1, x2, y2);

  int ox, oy, by, wid;

  // Sound
  wid = snddlg_olwid[0];
  ox = (DLG_WIDTH - wid) / 2;
  oy = FWIDTH + CAPTION_HEIGHT + 8;
  by = oy + CHECK_BOX_GAP + 2*CHECK_BOX_FRAME_HEIGHT;
  DipFrame(buf, ox, oy, ox+wid-1, by-1);

  // Open & Mark
  wid = snddlg_olwid[1];
  ox = FWIDTH + 8;
  oy += CHECK_BOX_FRAME_HEIGHT*2 + CHECK_BOX_GAP + SysFont->height;
  by = oy + 2*CHECK_BOX_GAP + 2*CHECK_BOX_FRAME_HEIGHT;
  DipFrame(buf, ox, oy, ox+wid-1, by-1);

  // Win & Die
  ox = DLG_WIDTH - (wid + 8 + FWIDTH) - 1;
  DipFrame(buf, ox, oy, ox+wid-1, by-1);

  // Swap Stereo
  wid = snddlg_olwid[2];
  ox = (DLG_WIDTH - wid) / 2;
  oy += CHECK_BOX_FRAME_HEIGHT*2 + 2*CHECK_BOX_GAP + SysFont->height;
  by = oy + CHECK_BOX_GAP + 2*CHECK_BOX_FRAME_HEIGHT;
  DipFrame(buf, ox, oy, ox+wid-1, by-1);

  DeleteBuffer(buf);
}


void SoundDlg::Run()
{
  Paint();
  RefreshWindow();
  SetFocus(OK);
  CatchMouse();
  CatchKeys();
  ws.RunEvents();
  ws.ResetEvents();
  ReleaseMouse();
  ReleaseKeys();
  if (isOK)
  {
    isSound    = sound->isChecked();
    SwapStereo = swap->isChecked();
    OpenSnd    = (open->isChecked() && open_snd);
    MarkSnd    = (mark->isChecked() && mark_snd);
    WinSnd     = (win->isChecked()  && win_snd);
    DieSnd     = (die->isChecked()  && die_snd);

    if (isSound) ws.StartSound();
    else	 ws.StopSound();
  }
}


void SoundDlg::cmOK()
{
  isOK = true;
  ws.StopRunningEvents();
}

void SoundDlg::cmCancel()
{
  isOK = false;
  ws.StopRunningEvents();
}
